#include "observer.h"
#include "coordtopocentric.h"

namespace libsgp4
{

/*
 * calculate lookangle between the observer and the passed in Eci object
 * 计算观察者与传入的Eci对象之间的视线角
 */
CoordTopocentric Observer::GetLookAngle(const Eci &eci)
{
    /*
     * update the observers Eci to match the time of the Eci passed in
     * if necessary
     * 如果必要的话，更新观察者的Eci以匹配传入的Eci
     */
    Update(eci.GetDateTime());

    /*
     * calculate differences
     * 计算差值，即相对速度，相对位置
     */
    Vector range_rate = eci.Velocity() - m_eci.Velocity();
    Vector range = eci.Position() - m_eci.Position();

    range.w = range.Magnitude();//计算相对位置的矢量大小（即两点之间的距离），并将其存储在range向量的w分量中。

    /*
     * Calculate Local Mean Sidereal Time for observers longitude
     * 计算观察者所在经度的地方平均恒星时LMST
     */
    double theta = eci.GetDateTime().ToLocalMeanSiderealTime(m_geo.longitude);

    double sin_lat = sin(m_geo.latitude);
    double cos_lat = cos(m_geo.latitude);
    double sin_theta = sin(theta);
    double cos_theta = cos(theta);
    //将ECI坐标转换为地平坐标系的等价形式，top_s/e/z分别是南向、东向、垂直分量
    double top_s = sin_lat * cos_theta * range.x
                   + sin_lat * sin_theta * range.y - cos_lat * range.z;
    double top_e = -sin_theta * range.x
                   + cos_theta * range.y;
    double top_z = cos_lat * cos_theta * range.x
                   + cos_lat * sin_theta * range.y + sin_lat * range.z;
    double az = atan(-top_e / top_s);
    //方位角azimuth是天体相对于观察者正北方向的角度，使用了-top_e，因为方位角通常定义为从北向东增加。

    /*如果天体在南方，那么仅仅使用atan(-top_e / top_s)计算出的方位角会是负的
     *在数学上，atan的结果在-π/2到π/2之间，因为它实际上是从正南方向开始逆时针测量的。
     *为了将方位角调整到从正北开始顺时针测量的标准范围，我们需要将结果加上π（或180°）。
     */
    if (top_s > 0.0)
    {
        az += kPI;
    }
    /*如果由于某种原因（比如计算误差）方位角仍然是负的，
     * 那么通过加上2π（或360°），我们可以确保方位角回到0到2π的标准范围内。
     *这实际上是将方位角绕圈旋转了一次，以确保其值是非负的。
     */
    if (az < 0.0)
    {
        az += 2.0 * kPI;
    }

    double el = asin(top_z / range.w);//仰角elevation是天体相对于观察者地平面的角度
    double rate = range.Dot(range_rate) / range.w;

    /*弧度制,km,km/s
     */
    return CoordTopocentric(az,
                            el,
                            range.w,
                            rate);
}

} // namespace libsgp4

